Imports Clo = Enhancements.Core.Logging
Imports Ere = Enhancements.Basic.RegularExpressions
Imports Gen = System.Collections.Generic
Imports Glo = System.Globalization
Imports Iou = System.IO
Imports Ref = System.Reflection
Imports Reg = System.Text.RegularExpressions
Imports Sys = System
Imports Tex = System.Text
Imports Xsd = System.Xml.Schema
Imports W3c = System.Xml
Imports Vbn = Microsoft.VisualBasic

Namespace Enhancements.Basic.Expressions.Values
    ''' <summary>Represents a token extracted from an expression that has a integer value.</summary>
    ''' <remarks>An integer value representation must end with the suffix specified by the TypeSpecifierRepresentation property. The given value must obey to the limits imposed by the Minimum and Maximum properties.</remarks>
    <Serializable(), DebuggerStepThrough()> _
    Public NotInheritable Class [Integer]
        Inherits Number

        Private Sub New(ByVal _expression As System.String, ByVal _expressionBeginIndex As Sys.Int32, ByVal _expressionEndIndex As Sys.Int32, ByVal _value As System.Int64)
            MyBase.New(_expression, _expressionBeginIndex, _expressionEndIndex, _value)
        End Sub

        ''' <summary>The associated framework type used for the token value storage.</summary>
        Public Shared ReadOnly Property UnderlyingType() As Sys.Type
            Get
                Dim _returnValue As Sys.Type = GetType(System.Int64)

                Return _returnValue
            End Get
        End Property

        ''' <summary>The suffix that these tokens representations must end with.</summary>
        Public Shared ReadOnly Property TypeSpecifierRepresentation() As System.String
            Get
                Dim _returnValue As System.String = ___Texts.ToUpper(String.Empty)

                Return _returnValue
            End Get
        End Property

        ''' <summary>The minimum value accepted for a integer token.</summary>
        Public Shared ReadOnly Property Minimum() As System.Int64
            Get
                Dim _returnValue As System.Int64 = 0

                Return _returnValue
            End Get
        End Property

        ''' <summary>The maximum value accepted for a integer token.</summary>
        Public Shared ReadOnly Property Maximum() As System.Int64
            Get
                Dim _returnValue As System.Int64 = Sys.Int64.MaxValue

                Return _returnValue
            End Get
        End Property

        Private Shared Function __Parse(ByVal _expression As System.String, ByVal _expressionBeginIndex As Sys.Int32) As Sys.Object
            Dim _returnValue As Sys.Object = Nothing
            Dim _returnValueStringBuilder As Tex.StringBuilder = Nothing
            If _expression.IsNullNot("_expression", False) AndAlso _expression.IsEmptyNot("_expression", False) AndAlso _expressionBeginIndex.IsInRange("_expressionBeginIndex", 0, _expression.Length - 1, False) Then
                If Sys.Char.IsDigit(_expression.Chars(_expressionBeginIndex)) Then
                    _returnValueStringBuilder = New Tex.StringBuilder(String.Empty)
                    For _counter As Sys.Int32 = _expressionBeginIndex To _expression.Length - 1
                        If Sys.Char.IsDigit(_expression.Chars(_counter)) Then
                            _returnValueStringBuilder.Append(_expression.Chars(_counter))
                        Else
                            Exit For
                        End If
                    Next _counter
                    Dim _dummy As Sys.Int64 = 0
                    If Sys.Int64.TryParse(_returnValueStringBuilder.ToString(), Glo.NumberStyles.AllowDecimalPoint, Glo.CultureInfo.InvariantCulture, _dummy) Then
                        If Assert.IsInRange(_dummy, "_dummy", Minimum, Maximum, False) Then
                            _returnValue = New [Integer](_expression, _expressionBeginIndex, _expressionBeginIndex + _returnValueStringBuilder.ToString().Length - 1 + TypeSpecifierRepresentation.Length, Sys.Int64.Parse(_returnValueStringBuilder.ToString(), Glo.CultureInfo.InvariantCulture))
                        End If
                    End If
                End If
            End If
            If Assert.IsNull(_returnValue, "_returnValue", False) Then
                _returnValue = IntegerParseException.___Create(_expression, _expressionBeginIndex)
            End If

            Return _returnValue
        End Function

        ''' <summary>Parses an expression for an integer value starting by a begin index.</summary>
        ''' <param name="_expression">Expression to parse.</param>
        ''' <param name="_expressionBeginIndex">Expression begin index to use.</param>
        ''' <exception cref="IntegerParseException">The operation did not produce a valid token.</exception>
        ''' <returns> </returns>
        Public Overloads Shared Function Parse(ByVal _expression As System.String, ByVal _expressionBeginIndex As Sys.Int32) As [Integer]
            Dim _returnValue As Sys.Object = __Parse(_expression, _expressionBeginIndex)
            If Assert.IsOfType(_returnValue, "_returnValue", GetType(IntegerParseException), False) Then
                IntegerParseException.___Throw(CType(_returnValue, IntegerParseException))
            End If

            Return CType(_returnValue, [Integer])
        End Function

        ''' <summary>Tries to parse an expression for an integer value starting by a begin index.</summary>
        ''' <param name="_expression">Expression to parse.</param>
        ''' <param name="_expressionBeginIndex">Expression begin index to use.</param>
        ''' <param name="_result">The result of the operation if possible. If not, null is returned.</param>
        ''' <returns> </returns>
        Public Overloads Shared Function TryParse(ByVal _expression As System.String, ByVal _expressionBeginIndex As Sys.Int32, ByRef _result As [Integer]) As System.Boolean
            Dim _returnValue As System.Boolean = False
            Dim _dummy As Sys.Object = __Parse(_expression, _expressionBeginIndex)
            If Assert.IsOfType(_dummy, "_dummy", GetType(IntegerParseException), False) Then
                _result = Nothing
                _returnValue = False
            Else
                _result = CType(_dummy, [Integer])
                _returnValue = True
            End If

            Return _returnValue
        End Function

        Friend Overloads Shared Function ___AssertIsValidValue(ByVal _value As Sys.Object) As System.Boolean
            Dim _returnValue As System.Boolean = False
            If Assert.IsNullNot(_value, "_value", False) Then
                If Assert.IsOfType(_value, "_value", [Integer].UnderlyingType, False) Then
                    Dim _valueInt64 As Sys.Int64 = CType(_value, Sys.Int64)
                    If _valueInt64.IsInRange("_valueInt64", Minimum, Maximum, False) Then
                        _returnValue = True
                    End If
                End If
            End If

            Return _returnValue
        End Function

        ''' <summary>Determines the token's correct representation for use in an expression.</summary>
        ''' <returns> </returns>
        Public Overrides Function ToRepresentation() As System.String
            Dim _returnValue As System.String = __ToRepresentation(CType(Value, System.Int64))

            Return _returnValue
        End Function

        ''' <summary>Determines the correct representation of an integer value for use in an expression.</summary>
        ''' <exception cref="IntegerRepresentationException">The operation did not produce a valid representation because of the input value nature.</exception>
        ''' <returns> </returns>
        Public Overloads Shared Function ToRepresentation(ByVal _value As System.Int64) As System.String
            If Not ___AssertIsValidValue(_value) Then
                IntegerRepresentationException.___Throw(_value)
            End If

            Dim _returnValue As System.String = __ToRepresentation(_value)

            Return _returnValue
        End Function

        Private Shared Function __ToRepresentation(ByVal _value As System.Int64) As System.String
            Dim _returnValue As System.String = ___Texts.ToUpper(_value)

            Return _returnValue
        End Function

        ''' <exception cref="IsNullException"> </exception>
        ''' <exception cref="IsListFilledNotException"> </exception>
        Friend Shared Function ___ParseAll(ByRef _tokens As Gen.List(Of Token)) As Sys.Int32
            _tokens.IsListFilled("_tokens", True)

            Dim _returnValue As Sys.Int32 = 0
            Dim _tokensNew As Gen.List(Of Token) = New Gen.List(Of Token)()
            For _counter1 As Sys.Int32 = 0 To _tokens.Count - 1
                If _tokens(_counter1).IsOfType("_tokens(_counter1)", GetType(Undetermined), False) Then
                    Dim _tokensToken As Undetermined = CType(_tokens(_counter1), Undetermined)
                    For _counter2 As Sys.Int32 = 0 To _tokensToken.ExpressionPart.Length - 1
                        Dim _integer As [Integer] = Nothing
                        If TryParse(_tokensToken.Expression, _tokensToken.ExpressionBeginIndex + _counter2, _integer) Then
                            _tokensNew.Add(_integer)
                            _counter2 += _integer.ExpressionPart.Length - 1
                            _returnValue += 1
                        Else
                            Undetermined.___AppendNewToEndOrReplaceLastWithNew(_tokensNew, _tokensToken.Expression, _tokensToken.ExpressionBeginIndex + _counter2, _tokensToken.ExpressionBeginIndex + _counter2)
                        End If
                    Next _counter2
                Else
                    _tokensNew.Add(_tokens(_counter1))
                End If
            Next _counter1
            _tokens = _tokensNew

            Return _returnValue
        End Function

    End Class
End Namespace
